package com.cc.wechat.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cc.wechat.common.ResultCode;
import com.cc.wechat.common.constants.ChatConstants;
import com.cc.wechat.entity.ChatSession;
import com.cc.wechat.entity.User;
import com.cc.wechat.entity.ChatGroup;
import com.cc.wechat.exception.BusinessException;
import com.cc.wechat.mapper.ChatGroupMapper;
import com.cc.wechat.mapper.ChatSessionMapper;
import com.cc.wechat.mapper.UserMapper;
import com.cc.wechat.service.ChatSessionService;
import com.cc.wechat.service.UserService;
import com.cc.wechat.dto.response.ChatSessionResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.BeanUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 会话服务实现类
 * 提供会话相关的业务逻辑实现，包括会话的创建、查询、更新和删除等操作
 *
 * @author cc
 * @since 2024-01-20
 */
@Service
@RequiredArgsConstructor
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements ChatSessionService {

    /**
     * 用户服务，用于获取当前登录用户信息
     */
    private final UserService userService;

    /**
     * 用户Mapper，用于查询用户基本信息
     */
    private final UserMapper userMapper;

    /**
     * 群组Mapper，用于查询群组基本信息
     */
    private final ChatGroupMapper chatGroupMapper;

    /**
     * 创建会话
     * @param targetId 目标用户或群组ID
     * @param type 会话类型（0:私聊 1:群聊）
     * @return 会话信息响应对象
     * @throws BusinessException 当操作失败时抛出业务异常
     */
    @Override
    @Transactional
    public ChatSessionResponse createOrGetSession(Long targetId, Integer type, String lastMessage) {
        User currentUser = userService.getCurrentUser();
        // 创建新会话
        ChatSession newSession = new ChatSession();
        newSession.setUserId(currentUser.getId());
        newSession.setTargetId(targetId);
        newSession.setType(type);
        newSession.setUnreadCount(0);
        newSession.setIsTop(ChatConstants.TopStatus.NOT_TOP);
        newSession.setStatus(ChatConstants.SessionStatus.NORMAL);
        newSession.setLastMessage(lastMessage);
        newSession.setLastMessageTime(LocalDateTime.now());
        save(newSession);
        
        // 将实体类转换为响应DTO返回
        return convertToResponse(newSession);
    }

    /**
     * 根据targetId获取会话
     * @param targetId 目标ID
     * @return 会话信息
     */
    @Override
    public ChatSessionResponse getSessionByTargetId(Long targetId) {
        ChatSession session = getById(targetId);
        if (session == null) {
            return null;
        }
        return convertToResponse(session);
    }

    /**
     * 获取当前用户的会话列表
     * 按置顶状态和最后消息时间倒序排序
     *
     * @return 会话列表响应对象
     */
    @Override
    public List<ChatSessionResponse> getSessionList() {
        User currentUser = userService.getCurrentUser();
        
        List<ChatSession> sessions = lambdaQuery()
                .eq(ChatSession::getUserId, currentUser.getId())
                .eq(ChatSession::getStatus, ChatConstants.SessionStatus.NORMAL)
                .orderByDesc(ChatSession::getIsTop)
                .orderByDesc(ChatSession::getLastMessageTime)
                .list();
                
        return sessions.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    /**
     * 更新会话的最后一条消息
     * 同时更新最后消息时间为当前时间
     *
     * @param sessionId 会话ID
     * @param message 消息内容
     * @throws BusinessException 当会话不存在时抛出异常
     */
    @Override
    @Transactional
    public void updateLastMessage(Long sessionId, String message) {
        boolean updated = lambdaUpdate()
                .eq(ChatSession::getId, sessionId)
                .eq(ChatSession::getStatus, ChatConstants.SessionStatus.NORMAL)
                .set(ChatSession::getLastMessage, message)
                .set(ChatSession::getLastMessageTime, LocalDateTime.now())
                .update();
                
        if (!updated) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ChatConstants.Message.SESSION_NOT_FOUND);
        }
    }

    /**
     * 增加会话未读消息数
     * 将未读消息数加1
     *
     * @param sessionId 会话ID
     * @throws BusinessException 当会话不存在时抛出异常
     */
    @Override
    @Transactional
    public void incrementUnreadCount(Long sessionId) {
        boolean updated = lambdaUpdate()
                .eq(ChatSession::getId, sessionId)
                .eq(ChatSession::getStatus, ChatConstants.SessionStatus.NORMAL)
                .setSql("unread_count = unread_count + 1")
                .update();
                
        if (!updated) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ChatConstants.Message.SESSION_NOT_FOUND);
        }
    }

    /**
     * 清空会话未读消息数
     * 将未读消息数设置为0
     *
     * @param sessionId 会话ID
     * @throws BusinessException 当会话不存在时抛出异常
     */
    @Override
    @Transactional
    public void clearUnreadCount(Long sessionId) {
        boolean updated = lambdaUpdate()
                .eq(ChatSession::getId, sessionId)
                .eq(ChatSession::getStatus, ChatConstants.SessionStatus.NORMAL)
                .set(ChatSession::getUnreadCount, 0)
                .update();
                
        if (!updated) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ChatConstants.Message.SESSION_NOT_FOUND);
        }
    }

    /**
     * 设置会话置顶状态
     * 更新会话的置顶状态
     *
     * @param sessionId 会话ID
     * @param isTop 是否置顶
     * @throws BusinessException 当会话不存在时抛出异常
     */
    @Override
    @Transactional
    public void setTopStatus(Long sessionId, Boolean isTop) {
        boolean updated = lambdaUpdate()
                .eq(ChatSession::getId, sessionId)
                .eq(ChatSession::getStatus, ChatConstants.SessionStatus.NORMAL)
                .set(ChatSession::getIsTop, isTop ? ChatConstants.TopStatus.TOP : ChatConstants.TopStatus.NOT_TOP)
                .update();
                
        if (!updated) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ChatConstants.Message.SESSION_NOT_FOUND);
        }
    }

    /**
     * 删除会话
     * 将会话状态设置为已删除
     *
     * @param sessionId 会话ID
     * @throws BusinessException 当会话不存在时抛出异常
     */
    @Override
    @Transactional
    public void deleteSession(Long sessionId) {
        boolean updated = lambdaUpdate()
                .eq(ChatSession::getId, sessionId)
                .eq(ChatSession::getStatus, ChatConstants.SessionStatus.NORMAL)
                .set(ChatSession::getStatus, ChatConstants.SessionStatus.DELETED)
                .update();
                
        if (!updated) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ChatConstants.Message.SESSION_NOT_FOUND);
        }
    }

    /**
     * 将会话实体转换为响应DTO，并可以指定最后一条消息
     * 
     * @param session 会话实体
     * @param lastMessage 最后一条消息
     * @return 会话响应DTO
     */
    private ChatSessionResponse convertToResponse(ChatSession session) {
        ChatSessionResponse response = new ChatSessionResponse();
        BeanUtils.copyProperties(session, response);

        // 根据会话类型获取目标信息
        if (session.getType().equals(ChatConstants.SessionType.PRIVATE)) {
            // 获取目标用户信息
            User targetUser = userMapper.selectById(session.getTargetId());
            if (targetUser != null) {
                response.setTargetName(targetUser.getNickname());
                response.setTargetAvatar(targetUser.getAvatar());
            }
        } else {
            // 获取目标群组信息
            ChatGroup targetGroup = chatGroupMapper.selectById(session.getTargetId());
            if (targetGroup != null) {
                response.setTargetName(targetGroup.getName());
                response.setTargetAvatar(targetGroup.getAvatar());
            }
        }

        return response;
    }
} 